#define NTDDI_VERSION NTDDI_VISTA
#define _WIN32_WINNT 0x602
#define OEMRESOURCE
#include <windows.h>
#include <shellapi.h>
#include <commctrl.h>
#include <stdio.h>
#include <locale.h>

HICON WINAPI loadic(LPCWSTR lpIconPath){
	if(!lstrcmpW(lpIconPath, L"App")) return LoadIcon(NULL, IDI_APPLICATION);
	if(!lstrcmpW(lpIconPath, L"Error")) return LoadIcon(NULL, IDI_ERROR);
	if(!lstrcmpW(lpIconPath, L"Warning")) return LoadIcon(NULL, IDI_WARNING);
	if(!lstrcmpW(lpIconPath, L"Info")) return LoadIcon(NULL, IDI_INFORMATION);
	
	return ExtractIconW(NULL, lpIconPath, 0);
	
}

DWORD WINAPI MyBalloon(int id, LPCWSTR szTitle, LPCWSTR szText, DWORD dwTimeout, HICON hIcon, BOOL bModify){
	//wprintf(L"%d %s\n", id, szText);
	NOTIFYICONDATAW nid = {0};
	nid.cbSize = sizeof(NOTIFYICONDATAW);
	nid.hWnd = GetConsoleWindow(); 
	nid.uFlags = NIF_INFO|NIF_ICON;
	nid.uID = id;
	nid.hIcon = hIcon;
	nid.hBalloonIcon = hIcon;
	nid.dwInfoFlags  = NIIF_LARGE_ICON;
	lstrcpyW(nid.szInfoTitle, szTitle);
	lstrcpyW(nid.szInfo, szText);
	
	Shell_NotifyIconW(bModify?NIM_MODIFY:NIM_ADD, &nid);
	Sleep(dwTimeout);
	lstrcpyW(nid.szInfo, L"");
	Shell_NotifyIconW(NIM_MODIFY, &nid);
	return GetLastError(); 
}


int main(int argc, char *argv[]){
	setlocale(LC_ALL, "chs");
	if(argc ==1) //Print help
	{
		fprintf(stderr, "Usage: TaskbarDrama.exe <FileName>\n");
		return 1;
	}
	
	FILE *input = fopen(argv[1], "r");
	if(!input){
		printf("Cannot open file %s!", argv[1]);
		return -1;
	}
	int lines;
	
	fscanf(input, "%d", &lines);
	if(lines < 0 || lines >255){
		printf("Error: Lines must be an integer between 0 and 256!\n");
		return 1;
	}
	
	HWND hConsole = GetConsoleWindow();
	
	
	wchar_t *lpszTitle = (wchar_t *)malloc(256 * sizeof(wchar_t));
	wchar_t *lpszText = (wchar_t *)malloc(256 * sizeof(wchar_t));
	wchar_t *lpszIconPath = (wchar_t *)malloc(256 * sizeof(wchar_t));
	bool *idsset = (bool *)malloc(256);
	
	DWORD dwTimeout = 1000;
	int add;
	//ShowWindow(hConsole, SW_HIDE);
	for(int i = 0; i < lines; i++){
		int id;
		int scanret = fwscanf(input, L"%d%s%s%d%s", &id, lpszTitle, lpszText, &dwTimeout, lpszIconPath);
		if(scanret == EOF) break;
		if(id < 0 || id > 255){
			printf("Invalid id at Line %d!\n", i+1);
			return 3;
		}
		bool newid = 0;
		if(!idsset[id]){
			newid = 1;idsset[id] = true;
		}
		
		HICON hIcon = loadic(lpszIconPath);
		if(!hIcon && lstrcmpW(lpszIconPath, L"Null")){
			printf("Invalid icon file at Line %d!\n", i+1);
			return 4;
		}
		MyBalloon(id, lpszTitle, lpszText, dwTimeout, hIcon, !newid);
	}
	
	for(int i = 0; i < 256; i++){
		if(!idsset[i]) continue;
		NOTIFYICONDATAW nid = {0};
		nid.cbSize = sizeof(NOTIFYICONDATAW);
		nid.hWnd =  hConsole;
		nid.uID = i;
		Shell_NotifyIconW(NIM_DELETE, &nid);
	}
	fclose(input);
	free(lpszTitle);free(lpszText);free(lpszIconPath);free(idsset);
	
	return 0;
	
} 
